home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX401.ATB / AHDI.S < prev    next >
Encoding:
Text File  |  2001-02-09  |  11.1 KB  |  523 lines

  1. * ahdi.s
  2.  
  3. *------------------------------------------------------------------------
  4. *                                    :
  5. *    ST SASI/AHDI hard disk driver                    :
  6. *    Copyright 1985 Atari Corp.                    :
  7. *                                    :
  8. * 14-Mar-1989 ml    Short version just for HDX.
  9. *                                    :
  10. *----                                    :
  11.  
  12. flock        equ    $43e        ; FIFO lock variable
  13. _hz_200        equ    $4ba        ; system 200hz timer
  14.  
  15.  
  16. * ---------------- Low-level driver ----------------
  17.  
  18. *----- Hardware:
  19. wdc        equ    $ffff8604
  20. wdl        equ    $ffff8606
  21. wdcwdl        equ    wdc        ; used for long writes
  22. xwdl        equ    wdl-wdc        ; offset from wdc to wdl
  23.  
  24. dmahi        equ    $ffff8609
  25. dmamid        equ    dmahi+2
  26. dmalow        equ    dmamid+2
  27. gpip        equ    $fffffa01
  28.  
  29.  
  30. *----- Tunable:
  31. ltimeout        equ    450000        ; long-timeout (3 S)
  32. stimeout        equ    15000        ; short-timeout (100 mS)
  33.  
  34. tocount:        dc.l    1        ; timeout counter
  35.  
  36. *+
  37. * LONG _qdone() - Wait for command byte handshake
  38. * LONG _fdone() - Wait for operation complete
  39. * Passed:    nothing
  40. *
  41. * Returns:    EQ: no timeout
  42. *        MI: timeout condition
  43. *
  44. * Uses:        D0
  45. *
  46. * each pass through the loop takes 6.75 uS
  47. *-
  48. _fdone:    move.l    #ltimeout,tocount
  49.     bra    qd1
  50.  
  51. _qdone:
  52.     move.l    #stimeout,tocount
  53. qd1:    subq.l    #1,tocount        ; drop timeout count
  54.     bmi    qdq            ; (i give up, return NE)
  55.     btst    #5,gpip            ; interrupt?
  56.     bne    qd1            ; (not yet)
  57.  
  58.     moveq    #0,d0            ; return EQ (no timeout)
  59.     rts
  60.  
  61. qdq:    moveq    #-1,d0
  62.     rts
  63.  
  64.  
  65. *+
  66. * WORD _endcmd()
  67. * Wait for end of SASI command
  68. * Passed:    d0 value to be written to wdl
  69. *
  70. * Returns:    EQ: success (error code in D0.W)
  71. *        MI: timeout
  72. *        NE: failure (SASI error code in D0.W)
  73. *
  74. * Uses:        d0,d1
  75. *-
  76. _endcmd: move    d0,d1            ; preserve wdl value
  77.  
  78.     bsr    _fdone            ; wait for operation complete
  79.     bmi    endce            ; (timed-out, so complain)
  80.  
  81.     move.w    d1,wdl
  82.     move.w    wdc,d0            ; get the result
  83.     and.w    #$00ff,d0        ; (clean it up), if non-zero should
  84.  
  85. endce:    rts                ;  do a ReadSense command to learn more
  86.  
  87.  
  88. *-
  89. * _hread(sectno, count, buf, dev)
  90. * LONG sectno;         4(sp)
  91. * WORD count;         8(sp)
  92. * LONG buf;        $a(sp)    $b=high, $c=mid, $d=low
  93. * WORD dev;        $e(sp)
  94. *
  95. * Returns:    -1 on timeout
  96. *        0 on success
  97. *        nonzero on error
  98. *
  99. *-
  100.     .globl    _hread
  101. _hread:
  102.     movea.l    #wdc,a0            ; pointer to DMA chip
  103.     st    flock            ; lock FIFO
  104.  
  105.     move    #$88,xwdl(a0)
  106.     clr.l    d0
  107.     move.w    $0e(sp),d0        ; get unit number
  108.     lsl.w    #5,d0
  109.     swap    d0
  110.     ori.l    #$0008008a,d0        ; 08 wdc, 8a wdl
  111.     move.l    d0,(a0) ; wdcwdl
  112.  
  113.     move.l    $a(sp),-(sp)        ; set DMA address
  114.     bsr    _setdma
  115.     addq    #4,sp
  116.  
  117.     bsr    _setss            ; set sector and size
  118.     bmi    _hto
  119.  
  120.     move.w    #$190,xwdl(a0)
  121.     move.w    #$90,xwdl(a0)
  122.     move.w    8(sp),(a0) ;wdc        ; write sector count to DMA chip
  123.     move.w    #$8a,xwdl(a0)
  124.     move.l    #$00000000,(a0) ; wdcwdl; control byte  0 wdc 0 wdl
  125.  
  126.     move.w    #$8a,d0
  127.     bsr    _endcmd
  128.  
  129. hrx:    bra    _hdone            ; cleanup after IRQ
  130.  
  131.  
  132. *-
  133. * _hwrite(sectno, count, buf, dev)
  134. * LONG sectno;         4(sp)
  135. * WORD count;         8(sp)
  136. * LONG buf;        $a(sp)    $b=high, $c=mid, $d=low
  137. * WORD dev;        $e(sp)
  138. *
  139. *-
  140.     .globl    _hwrite
  141. _hwrite:
  142.     movea.l    #wdc,a0            ; pointer to DMA chip
  143.     st    flock            ; lock FIFO
  144.  
  145.     move.l    $a(sp),-(sp)        ; set DMA address
  146.     bsr    _setdma
  147.     addq    #4,sp
  148.  
  149.     move.w    #$88,xwdl(a0)
  150.     clr.l    d0
  151.     move.w    $0e(sp),d0        ; get unit number
  152.     lsl.w    #5,d0
  153.     swap    d0
  154.     ori.l    #$000a008a,d0        ; 0a wdc 8a wdl
  155.     move.l    d0,(a0) ; wdcwdl
  156.  
  157.     bsr    _setss
  158.     bmi    _hto
  159.  
  160.     move.w    #$90,xwdl(a0)
  161.     move.w    #$190,xwdl(a0)
  162.     move.w    8(sp),(a0) ;wdc        ; sector count for DMA chip's benefit
  163.     move.w    #$18a,xwdl(a0)
  164.     move.l    #$00000100,(a0) ; wdcwdl
  165.  
  166.     move.w    #$18a,d0
  167.     bsr    _endcmd
  168.  
  169. hwx:    bra    _hdone            ; cleanup after IRQ
  170.  
  171.  
  172. *+
  173. * void _setdma(addr)
  174. * LONG addr;
  175. *-
  176. _setdma:
  177.     move.b    7(sp),dmalow
  178.     move.b    6(sp),dmamid
  179.     move.b    5(sp),dmahi
  180.     rts
  181.  
  182. *+
  183. * WORD _setss  -- set sector number and number of sectors
  184. *-
  185. _setss:    move.w    #$8a,xwdl(a0)
  186.  
  187.     bsr    _qdone            ; wait for controller to take command
  188.     bmi    setsse
  189.  
  190.     move.b    9(sp),d0        ; construct sector#
  191.     swap    d0
  192.     move.w    #$008a,d0
  193.     move.l    d0,(a0) ; wdcwdl    ; write MSB sector# + devno
  194.     bsr    _qdone
  195.     bmi    setsse
  196.  
  197.     move.b    10(sp),d0        ; write MidSB sector#
  198.     swap    d0
  199.     move.w    #$008a,d0
  200.     move.l    d0,(a0) ; wdcwdl
  201.     bsr    _qdone
  202.     bmi    setsse
  203.  
  204.     move.b    11(sp),d0        ; write LSB sector#
  205.     swap    d0
  206.     move.w    #$008a,d0
  207.     move.l    d0,(a0) ; wdcwdl
  208.     bsr    _qdone
  209.     bmi    setsse
  210.  
  211.     move.w    12(sp),d0        ; write sector count
  212.     swap    d0
  213.     move.w    #$008a,d0
  214.     move.l    d0,(a0) ; wdcwdl
  215.     bsr    _qdone
  216.  
  217. setsse:    rts
  218.  
  219.  
  220. _hto:    moveq    #-1,d0        ; indicate timeout
  221. _hdone:    move.w    #$80,wdl    ; Landon's code seems to presume we
  222.     tst.w    wdc
  223.     clr    flock        ; NOW, signal that we are done
  224.     rts
  225.  
  226.  
  227. * page 
  228. *+
  229. *  _doformat - format hard disk
  230. *
  231. *    Synopsis:    LONG _doformat(dev, interlv)
  232. *        WORD dev;            4(sp).W
  233. *        WORD interlv;            6(sp).W
  234. *
  235. *-
  236. acfmt:    dc.b    4    ; format command + devno (upper 3 bits)
  237.     dc.b    0    ; (unused)
  238.     dc.b    0    ; (unused) data pattern
  239. ac_in:    dc.b    0,0    ; interleave factor MSB, LSB
  240.     dc.b    0    ; reserved
  241.     even
  242.  
  243.     .globl    _doformat
  244. _doformat:
  245.     move.w    4(sp),d0        ; set dev#
  246.     lsl.b    #5,d0            ; up 5 bits, fill in 0s
  247.     or.b    #4,d0            ; OR-in with FORMAT command
  248.     move.b    d0,acfmt        ; stuff into command frame
  249.     move.b    6(sp),ac_in        ; set interleave
  250.     move.b    7(sp),ac_in+1
  251.  
  252.     lea    acfmt(pc),a0        ; pick up pointer to the command block
  253.     clr.w    d0
  254.     st    flock            ; lock FIFO
  255.     move.w    #$88,wdl
  256.     move.b    (a0)+,d0        ; get the command byte
  257.     swap    d0
  258.     move.w    #$8a,d0
  259.     move.l    d0,wdc            ; byte wdc 8a wdl
  260.  
  261.     moveq    #(5-1),d1        ; write remaining 5 bytes of command
  262. fmt1:    bsr    _qdone
  263.     bmi    _hto
  264.     move.b    (a0)+,d0        ; next byte of command
  265.     swap    d0
  266.     move.w    #$8a,d0
  267.     move.l    d0,wdcwdl
  268.     dbra    d1,fmt1
  269.  
  270. fmt2:    btst    #5,gpip            ; wait (forever) for completion
  271.     bne    fmt2
  272.     move.w    wdc,d0            ; get the status
  273.     andi.w    #$00FF,d0        ; only low byte is significant
  274.     bra    _hdone            ; cleanup after IRQ
  275.  
  276.  
  277. * page 
  278. *+
  279. *  _mode_set - set hard disk format parameters
  280. *
  281. *    Synopsis:    LONG _mode_set(dev, len, parms)
  282. *        WORD dev;            4(sp).W
  283. *        WORD len;            6(sp).W
  284. *        char *parms;            8(sp).L
  285. *
  286. *-
  287.     .globl    _mode_set
  288. _mode_set:
  289.     st    flock            ; lock FIFO
  290.     move.l    8(sp),-(sp)        ; -> parameter block address
  291.     bsr    _setdma            ; set DMA there
  292.     addq    #4,sp
  293.  
  294. * write command and dev#
  295.     move.w    #$88,wdl
  296.     move.w    4(sp),d0        ; d0 = (dev << 5) << 16
  297.     lsl.b    #5,d0
  298.     swap    d0            ; in upper word
  299.     or.l    #$0015008a,d0        ; write dev# + ModeSelect + FIFO bits
  300.     move.l    d0,wdcwdl        ; mdsel+dev wdc 8a wdl (byte 0)
  301.     bsr    _qdone
  302.     bmi    wdx
  303.  
  304.     move.l    #$0000008a,wdcwdl    ; byte 1
  305.     bsr    _qdone
  306.     bmi    wdx
  307.  
  308.     move.l    #$0000008a,wdcwdl    ; byte 2
  309.     bsr    _qdone
  310.     bmi    wdx
  311.  
  312.     move.l    #$0000008a,wdcwdl    ; byte 3
  313.     bsr    _qdone
  314.     bmi    wdx
  315.  
  316.     move.w    6(sp),d0        ; # bytes of parameter
  317.     swap    d0            ; in upper word
  318.     or.l    #$0000008a,d0
  319.     move.l    d0,wdcwdl        ; byte 4
  320.     bsr    _qdone
  321.     bmi    wdx
  322.  
  323.     move.w    #$90,wdl        ; reset the DMA chip
  324.     move.w    #$190,wdl
  325.     move.w    #$01,wdc        ; 1 sector of DMA (actually less)
  326.     move.w    #$18a,wdl
  327.     move.l    #$00000100,wdcwdl    ; byte 5 (control byte)
  328.     move.w    #$18a,d0        ; wdl value
  329.     bsr    _endcmd            ; wait for command completion
  330. wdx:    bra    _hdone
  331.  
  332.  
  333. * page 
  334. *+
  335. *  _md_sense - get hard disk format parameters
  336. *
  337. *    Synopsis:    LONG _md_sense(dev, parms)
  338. *        WORD dev;            4(sp).W
  339. *        char *parms;            6(sp).L
  340. *
  341. *-
  342.     .globl    _md_sense
  343. _md_sense:
  344.     st    flock            ; lock FIFO
  345.     move.l    6(sp),-(sp)        ; -> parameter block address
  346.     bsr    _setdma            ; set DMA there
  347.     addq    #4,sp
  348.  
  349. * write command and dev#
  350.     move.w    #$88,wdl
  351.     move.w    4(sp),d0        ; d0 = (dev << 5) << 16
  352.     lsl.b    #5,d0
  353.     swap    d0            ; in upper word
  354.     or.l    #$001a008a,d0        ; write dev# + ModeSense + FIFO bits
  355.     move.l    d0,wdcwdl        ; mdsense+dev wdc 8a wdl (byte 0)
  356.     bsr    _qdone
  357.     bmi    wdx1
  358.  
  359.     move.l    #$0000008a,wdcwdl    ; byte 1
  360.     bsr    _qdone
  361.     bmi    wdx1
  362.  
  363.     move.l    #$0000008a,wdcwdl    ; byte 2
  364.     bsr    _qdone
  365.     bmi    wdx1
  366.  
  367.     move.l    #$0000008a,wdcwdl    ; byte 3
  368.     bsr    _qdone
  369.     bmi    wdx1
  370.  
  371.     move.l    #$0016008a,wdcwdl    ; 22 bytes of parameters (byte 4)
  372.     bsr    _qdone
  373.     bmi    wdx1
  374.  
  375.     move.w    #$190,wdl        ; reset the DMA chip
  376.     move.w    #$90,wdl
  377.     move.w    #$01,wdc        ; 1 sector of DMA (actually less)
  378.     move.w    #$8a,wdl
  379.     move.l    #0,wdcwdl        ; byte 5 (control byte)
  380.     move.w    #$8a,d0            ; wdl value
  381.     bsr    _endcmd            ; wait for command completion
  382. wdx1:    bra    _hdone
  383.  
  384.  
  385. *
  386. *---------------
  387. *
  388. *  LONG _rq_sense() - get non-extended sense data from target
  389. *  LONG _rq_xsense() - get extended sense data from target
  390. *
  391. *  Passed:
  392. *    WORD physunit#;            4(sp).W        $6(sp).w
  393. *    char data[];            6(sp).L        $8(sp).l
  394. *
  395. *  Returns:
  396. *        0 : OK
  397. *    non-0 : ERROR
  398. *
  399.     .globl    _rq_sense
  400.     .globl    _rq_xsense
  401. _rq_sense:
  402.     moveq    #3,d2            ; do it 4 times
  403.     move.w    #0,-(sp)        ; request 4 bytes of sense data
  404.     bra.s    rq0
  405. _rq_xsense:
  406.     moveq    #0,d2            ; do it one time
  407.     move.w    #16,-(sp)        ; request 16 bytes of sense data
  408. rq0:    movea.l    #wdc,a0
  409.     st    flock            ; lock FIFO
  410.     move.l    8(sp),-(sp)        ; -> sense data buffer address
  411.     bsr    _setdma            ; set DMA there
  412.     addq.l    #4,sp
  413.  
  414.      move.w    #$190,xwdl(a0)    ;wdl    ; reset the DMA chip
  415.     move.w    #$90,xwdl(a0)    ;wdl
  416.     move.w    #$01,(a0)    ;wdc    ; 1 sector of DMA (actually less)
  417.  
  418.     moveq    #0,d0
  419. rq1:    move.l    _hz_200,d1        ; kludge delay
  420.     addq.l    #2,d1
  421. rq2:    cmp.l    _hz_200,d1
  422.     bcc.s    rq2
  423.     move.w    #$88,xwdl(a0)    ;wdl
  424.     move.w    6(sp),d0        ; d0 = (dev << 5) << 16
  425.     lsl.b    #5,d0
  426.     swap    d0            ; in upper word
  427.     or.l    #$0003008a,d0        ; write dev#+Request Sense+FIFO bits
  428.     move.l    d0,(a0)        ;wdcwdl    ; rqsense+dev wdc 8a wdl (byte 0)
  429.     bsr    _qdone
  430.     bmi.s    wdq1
  431.  
  432.     move.l    #$8a,d1            ; byte to be sent
  433.     move.l    d1,(a0)        ;wdcwdl    ; byte 1
  434.     bsr    _qdone
  435.     bmi.s    wdq1
  436.  
  437.     move.l    d1,(a0)        ;wdcwdl    ; byte 2
  438.     bsr    _qdone
  439.     bmi.s    wdq1
  440.  
  441.     move.l    d1,(a0)        ;wdcwdl    ; byte 3
  442.     bsr    _qdone
  443.     bmi.s    wdq1
  444.  
  445.     move.w    (sp),d0            ; # bytes of sense data requested
  446.     swap    d0
  447.     or.l    d1,d0
  448.     move.l    d0,(a0)        ;wdcwdl    ; byte 4
  449.     bsr    _qdone
  450.     bmi.s    wdq1
  451.  
  452.     move.w    #$8a,xwdl(a0)    ;wdl
  453.     move.l    #0,(a0)        ;wdcwdl    ; byte 5 (control byte)
  454.     move.w    #$8a,d0            ; wdl value
  455.     bsr    _endcmd            ; wait for command completion
  456.     tst.w    d0
  457.     bmi.s    wdq1
  458.     dbra    d2,rq1            ; go back until done
  459. wdq1:    addq.l    #2,sp            ; clean up stack
  460.     bra    _hdone
  461.  
  462.  
  463. ;
  464. ;----------------
  465. ;
  466. ;  _inquiry - get device-specific parameters
  467. ;
  468. ;    Synopsis:    LONG _inquiry(physunit#, parms)
  469. ;        WORD physunit#;            4(sp).W
  470. ;        char *parms;            6(sp).L
  471. ;
  472. ; Old driver uses these two lines which do NOT do 
  473. ; "d0 = (dev << 5) << 16" because the hi word of
  474. ; D0 before the swap (lo word after) is garbage.
  475. ;    lsl.b    #5,d0
  476. ;    swap    d0
  477. ;-
  478.     .globl    _inquiry
  479. _inquiry:
  480.     st    flock            ; lock FIFO
  481.     move.l    6(sp),-(sp)        ; -> parameter block address
  482.     bsr    _setdma            ; set DMA there
  483.     addq.l    #4,sp
  484.     movea.l    #wdc,a0            ; pointer to DMA chip
  485. ; write command and phyunit#
  486.     move.w    #$88,xwdl(a0)    ;wdl
  487.     move.w    4(sp),d0        ; d0 = (physunit# << 5) << 16
  488.     moveq    #21,d1
  489.     lsl.l    d1,d0            
  490.     or.l    #$0012008a,d0        ; write physunit# + Inquiry + FIFO bits
  491.     move.l    d0,(a0)        ;wdcwdl    ; inquiry+physunit# wdc 8a wdl (byte 0)
  492.     bsr    _qdone
  493.     bmi    inq
  494.  
  495.     move.l    #$8a,d1            ; d1 = byte to be sent
  496.     move.l    d1,(a0)        ;wdcwdl    ; byte 1
  497.     bsr    _qdone
  498.     bmi    inq
  499.  
  500.     move.l    d1,(a0)        ;wdcwdl    ; byte 2
  501.     bsr    _qdone
  502.     bmi    inq
  503.  
  504.     move.l    d1,(a0)        ;wdcwdl    ; byte 3
  505.     bsr    _qdone
  506.     bmi    inq
  507.  
  508.     move.l    #$0010008a,(a0)    ;wdcwdl    ; 16 byte of parameters (byte 4)
  509.     bsr    _qdone
  510.     bmi    inq
  511.  
  512.     move.w    #$190,xwdl(a0)    ;wdl    ; reset the DMA chip
  513.     move.w    #$90,xwdl(a0)    ;wdl
  514.     move.w    #$01,(a0)    ;wdc    ; 1 sector of DMA (actually less)
  515.     move.w    #$8a,xwdl(a0)    ;wdl
  516.     move.l    #0,(a0)        ;wdcwdl    ; byte 5 (control byte)
  517.     move.w    #$8a,d0            ; wdl value
  518.     bsr    _endcmd            ; wait for command completion
  519. inq:    bra    _hdone
  520.  
  521.  
  522.  
  523.